package person.drf.shop.product.thread;

import java.util.concurrent.*;

public class ThreadTest {
    //系统自带固定式线程池
    public static ExecutorService threadPool = Executors.newFixedThreadPool(10);

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        CompletableFuture<Object> future01 = CompletableFuture.supplyAsync(() -> {
            System.out.println("查找商品图片信息");
            return "商品图片.jpg";
        }, threadPool);

        CompletableFuture<Object> future02 = CompletableFuture.supplyAsync(() -> {
            System.out.println("查找商品属性");
            return "黑色+256G";
        }, threadPool);

        CompletableFuture<Object> future03 = CompletableFuture.supplyAsync(() -> {
            System.out.println("查找商品介绍");
            return "华为";
        }, threadPool);

        CompletableFuture<Object> anyOf = CompletableFuture.anyOf(future01, future02, future03);
        System.out.println(Thread.currentThread().getName()+"--"+anyOf.get());

//        CompletableFuture<Void> allOf = CompletableFuture.allOf(future01, future02, future03);
//        allOf.get(); //等待三个任务都完成才执行下面
//        System.out.println(Thread.currentThread().getName()+"--"
//                +future01.get()+"--"+future02.get()+"--"+future03.get());
    }

    //两个其中一个完成，即可开始任务3
    private static void BothOneOf() throws InterruptedException, ExecutionException {
        CompletableFuture<Object> future01 = CompletableFuture.supplyAsync(() -> {
            System.out.println("任务1线程："+Thread.currentThread().getName());
            int i = 10/2;
            System.out.println("任务1线程结束"+Thread.currentThread().getName());
            return i;
        }, threadPool);

        CompletableFuture<Object> future02 = CompletableFuture.supplyAsync(() -> {
            System.out.println("任务2线程："+Thread.currentThread().getName());
            try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) { e.printStackTrace(); }
            System.out.println("任务2线程结束");
            return "haha!!";
        }, threadPool);

        CompletableFuture<Object> future03 = future01.applyToEitherAsync(future02, (res) -> {
            System.out.println("任务3执行..");
            return res;
        }, threadPool);
        System.out.println(Thread.currentThread().getName()+future03.get());
    }

    //两组都要完成，即可开启任务3
    private static void bothAll() throws InterruptedException, ExecutionException {
        CompletableFuture<Integer> future01 = CompletableFuture.supplyAsync(() -> {
            System.out.println("任务1线程："+Thread.currentThread().getName());
            int i = 10/5;
            System.out.println("任务1线程结束"+Thread.currentThread().getName());
            return i;
        }, threadPool);

        CompletableFuture<String> future02 = CompletableFuture.supplyAsync(() -> {
            System.out.println("任务2线程："+Thread.currentThread().getName());
            System.out.println("任务2线程结束");
            return "haha!!";
        }, threadPool);

        CompletableFuture<String> future03 = future01.thenCombineAsync(future02, (f1, f2) -> {
            return f1 +"--"+ f2;
        }, threadPool);
        System.out.println(Thread.currentThread().getName()+"--"+future03.get());

//        future01.thenAcceptBothAsync(future02,(f1,f2)->{
//            System.out.println("任务3开始..."+f1+"---"+f2);
//        },threadPool);
//        future01.runAfterBothAsync(future02,()->{
//            System.out.println("任务3开始...");
//        },threadPool);
    }

    private static void chuangxinghua() throws InterruptedException, ExecutionException {
        CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
            System.out.println("执行线程"+Thread.currentThread().getName());
            return 10/2;
        }, threadPool).thenApplyAsync((res)->{
            System.out.println("任务2启动了"+res);
            return res*2;
        },threadPool);
        System.out.println("main--end.............."+future.get());
    }

    private static void TestHandle() throws InterruptedException, ExecutionException {
        System.out.println("main--start............");
        CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
            System.out.println("执行线程"+Thread.currentThread().getName());
            return 10/0;
        }, threadPool).handle((result,exe)->{  //传入函数型接口，有参有返回
            if(result!=null){  //如果有结果
                System.out.println(result);
                return result;
            }
            if(exe!=null){  //如果有异常
                System.out.println(exe);
                return 10;
            }
            return 10;
        });
        System.out.println("main--end.............."+future.get());
    }

    private static void whencomplate() throws InterruptedException, ExecutionException {

        System.out.println("main--start............");
        //  supplyAsync(Supplier<U> 供给型接口，无参有返 ,  Executor)
        CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
            System.out.println("执行线程"+Thread.currentThread().getName());
            return 10/0;
        }, threadPool).whenComplete((result,Exception)->{  //能感知异常，但无法修改返回数据
            //whenComplete( Bigsumer(结果，异常))  传入的是消费性函数,有参无返
            System.out.println("请求成功"+result);
            System.out.println("请求失败"+Exception);
        }).exceptionally(throwable -> {                    //能感知异常，并返回一个默认数据
            return 10;
        });
        System.out.println("main--end.............."+future.get());
    }

    private static void TestRunAsync() {
        //  runAsync（Runnable,Executor）
        System.out.println("main.start............");
        CompletableFuture<Void> completableFuture = CompletableFuture.runAsync(() -> {
            System.out.println("当前线程" + Thread.currentThread().getName());
            System.out.println("运行结果" + (10 / 2));
        }, threadPool);
        System.out.println("main.end..............");
    }
}
